"""
认证系统数据库初始化脚本
"""

import asyncio
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from datetime import datetime

from app.core.database import engine, AsyncSessionLocal
from app.models.auth import User, Role, Permission, UserRole, RolePermission
from app.core.security import get_password_hash
from app.core.logger import logger


async def init_permissions(db: AsyncSession):
    """初始化系统权限"""
    permissions_data = [
        # 用户管理权限
        ("user.view", "查看用户", "查看用户信息", "user", "view", True),
        ("user.create", "创建用户", "创建新用户", "user", "create", True),
        ("user.update", "更新用户", "更新用户信息", "user", "update", True),
        ("user.delete", "删除用户", "删除用户", "user", "delete", True),
        ("user.manage", "管理用户", "完整的用户管理权限", "user", "manage", True),
        
        # 角色管理权限
        ("role.view", "查看角色", "查看角色信息", "role", "view", True),
        ("role.create", "创建角色", "创建新角色", "role", "create", True),
        ("role.update", "更新角色", "更新角色信息", "role", "update", True),
        ("role.delete", "删除角色", "删除角色", "role", "delete", True),
        ("role.assign", "分配角色", "为用户分配角色", "role", "assign", True),
        
        # 权限管理权限
        ("permission.view", "查看权限", "查看权限信息", "permission", "view", True),
        ("permission.assign", "分配权限", "为角色分配权限", "permission", "assign", True),
        
        # 数据血缘权限
        ("lineage.view", "查看血缘", "查看数据血缘图", "lineage", "view", True),
        ("lineage.analyze", "分析血缘", "执行血缘分析", "lineage", "analyze", True),
        ("lineage.manage", "管理血缘", "管理血缘数据", "lineage", "manage", True),
        
        # 任务管理权限
        ("task.view", "查看任务", "查看解析任务", "task", "view", True),
        ("task.create", "创建任务", "创建解析任务", "task", "create", True),
        ("task.execute", "执行任务", "执行解析任务", "task", "execute", True),
        ("task.manage", "管理任务", "完整的任务管理权限", "task", "manage", True),
        
        # 系统管理权限
        ("system.config", "系统配置", "系统配置管理", "system", "config", True),
        ("system.monitor", "系统监控", "系统监控查看", "system", "monitor", True),
        ("system.log", "系统日志", "查看系统日志", "system", "log", True),
    ]
    
    for name, display_name, description, resource, action, is_system in permissions_data:
        # 检查权限是否已存在
        stmt = select(Permission).where(Permission.name == name)
        result = await db.execute(stmt)
        existing_permission = result.scalar_one_or_none()
        
        if not existing_permission:
            permission = Permission(
                name=name,
                display_name=display_name,
                description=description,
                resource=resource,
                action=action,
                is_system=is_system
            )
            db.add(permission)
    
    await db.commit()
    logger.info("权限初始化完成")


async def init_roles(db: AsyncSession):
    """初始化系统角色"""
    roles_data = [
        ("admin", "系统管理员", "拥有所有权限的系统管理员", True),
        ("analyst", "数据分析师", "数据血缘分析和查看权限", True),
        ("operator", "系统操作员", "基本的系统操作权限", True),
        ("viewer", "查看者", "只读权限，可查看数据血缘", True),
    ]
    
    for name, display_name, description, is_system in roles_data:
        # 检查角色是否已存在
        stmt = select(Role).where(Role.name == name)
        result = await db.execute(stmt)
        existing_role = result.scalar_one_or_none()
        
        if not existing_role:
            role = Role(
                name=name,
                display_name=display_name,
                description=description,
                is_system=is_system
            )
            db.add(role)
    
    await db.commit()
    logger.info("角色初始化完成")


async def init_role_permissions(db: AsyncSession):
    """初始化角色权限关联"""
    # 管理员拥有所有权限
    stmt = select(Role).where(Role.name == "admin")
    result = await db.execute(stmt)
    admin_role = result.scalar_one_or_none()
    
    if admin_role:
        stmt = select(Permission)
        result = await db.execute(stmt)
        all_permissions = result.scalars().all()
        
        for permission in all_permissions:
            # 检查是否已存在关联
            stmt = select(RolePermission).where(
                RolePermission.role_id == admin_role.id,
                RolePermission.permission_id == permission.id
            )
            result = await db.execute(stmt)
            existing = result.scalar_one_or_none()
            
            if not existing:
                role_permission = RolePermission(
                    role_id=admin_role.id,
                    permission_id=permission.id,
                    granted_at=get_shanghai_now()
                )
                db.add(role_permission)
    
    # 数据分析师权限
    stmt = select(Role).where(Role.name == "analyst")
    result = await db.execute(stmt)
    analyst_role = result.scalar_one_or_none()
    
    if analyst_role:
        analyst_permissions = [
            "lineage.view", "lineage.analyze", "task.view", 
            "task.create", "task.execute", "user.view"
        ]
        
        for perm_name in analyst_permissions:
            stmt = select(Permission).where(Permission.name == perm_name)
            result = await db.execute(stmt)
            permission = result.scalar_one_or_none()
            
            if permission:
                # 检查是否已存在关联
                stmt = select(RolePermission).where(
                    RolePermission.role_id == analyst_role.id,
                    RolePermission.permission_id == permission.id
                )
                result = await db.execute(stmt)
                existing = result.scalar_one_or_none()
                
                if not existing:
                    role_permission = RolePermission(
                        role_id=analyst_role.id,
                        permission_id=permission.id,
                        granted_at=get_shanghai_now()
                    )
                    db.add(role_permission)
    
    # 系统操作员权限
    stmt = select(Role).where(Role.name == "operator")
    result = await db.execute(stmt)
    operator_role = result.scalar_one_or_none()
    
    if operator_role:
        operator_permissions = [
            "lineage.view", "task.view", "task.execute", 
            "user.view", "system.monitor"
        ]
        
        for perm_name in operator_permissions:
            stmt = select(Permission).where(Permission.name == perm_name)
            result = await db.execute(stmt)
            permission = result.scalar_one_or_none()
            
            if permission:
                # 检查是否已存在关联
                stmt = select(RolePermission).where(
                    RolePermission.role_id == operator_role.id,
                    RolePermission.permission_id == permission.id
                )
                result = await db.execute(stmt)
                existing = result.scalar_one_or_none()
                
                if not existing:
                    role_permission = RolePermission(
                        role_id=operator_role.id,
                        permission_id=permission.id,
                        granted_at=get_shanghai_now()
                    )
                    db.add(role_permission)
    
    # 查看者权限
    stmt = select(Role).where(Role.name == "viewer")
    result = await db.execute(stmt)
    viewer_role = result.scalar_one_or_none()
    
    if viewer_role:
        viewer_permissions = ["lineage.view", "task.view"]
        
        for perm_name in viewer_permissions:
            stmt = select(Permission).where(Permission.name == perm_name)
            result = await db.execute(stmt)
            permission = result.scalar_one_or_none()
            
            if permission:
                # 检查是否已存在关联
                stmt = select(RolePermission).where(
                    RolePermission.role_id == viewer_role.id,
                    RolePermission.permission_id == permission.id
                )
                result = await db.execute(stmt)
                existing = result.scalar_one_or_none()
                
                if not existing:
                    role_permission = RolePermission(
                        role_id=viewer_role.id,
                        permission_id=permission.id,
                        granted_at=get_shanghai_now()
                    )
                    db.add(role_permission)
    
    await db.commit()
    logger.info("角色权限关联初始化完成")


async def init_superuser(db: AsyncSession):
    """初始化超级用户"""
    # 检查是否已存在超级用户
    stmt = select(User).where(User.is_superuser == True)
    result = await db.execute(stmt)
    superuser = result.scalar_one_or_none()
    
    if superuser:
        logger.info(f"超级用户已存在: {superuser.username}")
        return
    
    # 创建默认超级用户
    stmt = select(Role).where(Role.name == "admin")
    result = await db.execute(stmt)
    admin_role = result.scalar_one_or_none()
    
    superuser = User(
        username="admin",
        email="admin@dataplexus.com",
        password_hash=get_password_hash("Admin123!"),
        full_name="系统管理员",
        is_active=True,
        is_superuser=True,
        password_changed_at=get_shanghai_now()
    )
    
    db.add(superuser)
    await db.flush()  # 获取用户ID
    
    # 分配管理员角色
    if admin_role:
        user_role = UserRole(
            user_id=superuser.id,
            role_id=admin_role.id,
            assigned_at=get_shanghai_now()
        )
        db.add(user_role)
    
    await db.commit()
    
    logger.info("超级用户创建成功:")
    logger.info("  用户名: admin")
    logger.info("  密码: Admin123!")
    logger.info("  邮箱: admin@dataplexus.com")


async def init_demo_users(db: AsyncSession):
    """初始化演示用户"""
    demo_users = [
        {
            "username": "analyst1",
            "email": "analyst1@dataplexus.com",
            "password": "Analyst123!",
            "full_name": "数据分析师1",
            "role": "analyst"
        },
        {
            "username": "operator1", 
            "email": "operator1@dataplexus.com",
            "password": "Operator123!",
            "full_name": "系统操作员1",
            "role": "operator"
        },
        {
            "username": "viewer1",
            "email": "viewer1@dataplexus.com", 
            "password": "Viewer123!",
            "full_name": "查看者1",
            "role": "viewer"
        }
    ]
    
    for user_data in demo_users:
        # 检查用户是否已存在
        stmt = select(User).where(User.username == user_data["username"])
        result = await db.execute(stmt)
        existing_user = result.scalar_one_or_none()
        
        if existing_user:
            continue
        
        # 获取角色
        stmt = select(Role).where(Role.name == user_data["role"])
        result = await db.execute(stmt)
        role = result.scalar_one_or_none()
        
        # 创建用户
        user = User(
            username=user_data["username"],
            email=user_data["email"],
            password_hash=get_password_hash(user_data["password"]),
            full_name=user_data["full_name"],
            is_active=True,
            is_superuser=False,
            password_changed_at=get_shanghai_now()
        )
        
        db.add(user)
        await db.flush()  # 获取用户ID
        
        # 分配角色
        if role:
            user_role = UserRole(
                user_id=user.id,
                role_id=role.id,
                assigned_at=get_shanghai_now()
            )
            db.add(user_role)
    
    await db.commit()
    logger.info("演示用户创建完成")


async def init_auth_database():
    """初始化认证系统数据库"""
    logger.info("开始初始化认证系统数据库...")
    
    try:
        # 创建表
        logger.info("1. 创建数据库表...")
        async with engine.begin() as conn:
            from app.models.auth import User, Role, Permission, UserRole, RolePermission, UserSession
            from app.core.database import Base
            from app.utils.timezone_utils import get_shanghai_now
            await conn.run_sync(Base.metadata.create_all)
        
        # 初始化数据
        async with AsyncSessionLocal() as db:
            logger.info("2. 初始化权限数据...")
            await init_permissions(db)
            
            logger.info("3. 初始化角色数据...")
            await init_roles(db)
            
            logger.info("4. 初始化角色权限关联...")
            await init_role_permissions(db)
            
            logger.info("5. 初始化超级用户...")
            await init_superuser(db)
            
            logger.info("6. 初始化演示用户...")
            await init_demo_users(db)
        
        logger.info("认证系统数据库初始化完成!")
        
    except Exception as e:
        logger.error(f"认证系统数据库初始化失败: {e}")
        raise


if __name__ == "__main__":
    asyncio.run(init_auth_database())
